import _ from 'lodash';
import moment from 'moment';
import { message } from 'antd';
import type { IOrginDealElementOptions } from './type';

// 处理交易单元数据
export const getDealElementOptions = (data: any[]) => {
  const _settlemen: any = [];
  let dataObj: Record<string, any> = {};
  const modalData = data?.map((item: any) => {
    // const children = item?.children?.map((n) => ({
    //   ...n,
    //   title: n?.label,
    //   key: n?.value,
    //   parentKey: item?.id,
    //   regionId: item?.value || '',
    // }));
    return { ...item, key: item?.id, title: item?.label || '' };
  });
  dataObj = { ...dataObj, ..._.groupBy(modalData, 'value') };
  return { modalData, value: modalData, dataObj };
};

// 处理交易单元数据
export const getAllDealElementOptions = (data: IOrginDealElementOptions[]) => {
  const _settlemen: Record<string, any> = {};
  let dataObj: Record<string, any> = {};
  const modalData: any[] = data.map((m: IOrginDealElementOptions) => {
    const children = m?.children?.map((n) => ({
      ...n,
      title: n?.label,
      key: n?.value,
      parentKey: m?.id,
      regionId: m?.value || '',
    }));

    dataObj = { ...dataObj, ..._.groupBy(children, 'value') };
    _settlemen[_.uniqueId()] = children;
    return { ...m, title: m?.label || '', children: children, key: m?.value || '' };
  });
  return { modalData, value: _.flatten(Object.values(_settlemen)), dataObj };
};

// 初始日历数据
export const initValue = (value: any) => {
  return Number(moment(value).format('DD'));
};

// 生成数组
export const repeatMonth = () => {
  const arr = Array.from({ length: 31 }, (v, i) => ({
    label: i + 1,
    value: i + 1,
  }));
  return arr;
};

// 对象数组去重
export const uniqueFunc = (arr: any, uniId: string) => {
  const res = new Map();
  return arr.filter((item: any) => !res.has(item[uniId]) && res.set(item[uniId], 1));
};

// 判断该用户是否有权限
export const havePermissions = (buttonType: string, buttonPermissions: any) => {
  const hasSave =
    buttonPermissions?.filter((item: any) => item.menuCode === buttonType)?.length > 0;
  if (!hasSave) {
    message.info('请联系管理员获取相关权限');
    return false;
  } else {
    return true;
  }
};

// 数据保留小数位
export const ToFixed = (data: any, persion = 3) => {
  if (!data || isNaN(data) || isNaN(Number(data))) return data;
  const dot = String(data).indexOf('.');
  let num = Number(data);
  if (dot !== -1) {
    const dotCnt = String(data).substring(dot + 1, data.length);
    if (dotCnt.length > persion) {
      num = Number(Number(data).toFixed(persion));
    } else {
      num = Number(data);
    }
  }
  return num;
};

export const TIME_ENUM = (point: 96 | 24, format: string = 'HHmm') => {
  const startTimeNum = format === 'HHmm' ? '0000' : '00:00';
  const startPointNum = format === 'HHmm' ? '2400' : '24:00';
  const timeArr = new Array(point);
  const time = moment().startOf('date');
  const pointArray: string[] = [];
  if (point === 96) {
    _.forEach(timeArr, () => {
      time.add(15, 'minutes');
      const timeData = `${
        time.format(format) === startTimeNum ? startPointNum : time.format(format)
      }`;
      pointArray.push(timeData);
    });
  } else {
    _.forEach(timeArr, () => {
      time.add(60, 'minutes');
      const timeData = `${
        time.format(format) === startTimeNum ? startPointNum : time.format(format)
      }`;
      pointArray.push(timeData);
    });
  }
  return pointArray;
};

/**
 *  树形数组扁平化
 * @param {Array} arrs 树形数据
 * @param {string} childs 树形数据子数据的属性名,常用'children'
 * @param {Array} attrArr 需要提取的公共属性数组(默认是除了childs的全部属性)
 * @returns
 */
export const extractTree = (arrs: any, childs?: string, attrArr?: string[]) => {
  let attrList: any = [];
  if (!Array.isArray(arrs) && !arrs?.length) return [];
  if (typeof childs !== 'string') return [];
  if (!Array.isArray(attrArr) || (Array.isArray(attrArr) && !attrArr.length)) {
    attrList = Object.keys(arrs[0]);
    attrList.splice(attrList.indexOf(childs), 1);
  } else {
    attrList = attrArr;
  }
  const list: any = [];
  const getObj = (arr: any) => {
    arr.forEach((row: any) => {
      const obj: any = {};
      attrList.forEach((item: any) => {
        obj[item] = row[item];
      });
      list.push(obj);
      if (row[childs]) {
        getObj(row[childs]);
      }
    });
    return list;
  };
  return getObj(arrs);
};

export const maxTotalReward = (rewardValues: number[]): number => {
  const _rewardValues = rewardValues.map((str: any) => Math.round(Number(str)));
  const n = _rewardValues.length;
  _rewardValues.sort((a, b) => a - b);
  if (n >= 2 && _rewardValues[n - 2] == _rewardValues[n - 1] - 1) {
    return 2 * _rewardValues[n - 1] - 1;
  }
  let f = BigInt(1);
  for (const x of _rewardValues) {
    const mask = (BigInt(1) << BigInt(x)) - BigInt(1);
    f = f | ((f & mask) << BigInt(x));
  }
  return f.toString(2).length - 1;
};

export const maxTotal = (rewardValues: number[]): number => {
  const values = new Set(rewardValues);
  rewardValues = Array.from(values).sort((a, b) => b - a);

  const max = rewardValues[0];
  const max2 = rewardValues[1] ?? 0;

  const min = rewardValues[rewardValues.length - 1];
  const min2 = Math.max(rewardValues[rewardValues.length - 2] ?? 0, min + 1);

  if (min + min2 > max) {
    return max + max2;
  }

  const canITakeResult = new Map<number, boolean>();

  for (let i = max - 1; i >= max2; i--) {
    if (canITake(i)) {
      return max + i;
    }
  }

  return max;

  function canITake(target: number): boolean {
    if (values.has(target)) return true;
    let ans = canITakeResult.get(target);
    if (ans != null) return ans;
    ans = false;
    if (target / 2 < values.size) {
      for (let x = 1; x < target / 2; x++) {
        const v = target - x;
        if (values.has(v) && canITake(x)) {
          ans = true;
          break;
        }
      }
    } else {
      for (const v of rewardValues) {
        const x = target - v;
        if (x >= v) break;
        if (canITake(x)) {
          ans = true;
          break;
        }
      }
    }
    canITakeResult.set(target, ans);
    return ans;
  }
};
